package cn.cangnova.cangjie.lexer;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;

import static com.intellij.psi.TokenType.BAD_CHARACTER;
import static com.intellij.psi.TokenType.WHITE_SPACE;
import static cn.cangnova.cangjie.psi.CjTokens.*;

%%

%{
  public _CangJieLexer() {
    this((java.io.Reader)null);
  }
%}

%public
%class _CangJieLexer
%implements FlexLexer
%function advance
%type IElementType
%unicode

EOL=\R


/* 空白字符
 * =======
 */
WHITE_SPACE_CHAR=[\ \n\t\f]          // 空格、换行、制表符、换页符

// 标识符基本组成
LETTER = [:letter:]|_                 // 字母或下划线
IDENTIFIER_PART=[:digit:]|{LETTER}    // 标识符组成部分：数字、字母或下划线
IDENTIFIER_START={LETTER}             // 标识符起始字符：字母或下划线

// 标识符类型

PLAIN_IDENTIFIER={IDENTIFIER_START}{IDENTIFIER_PART}*  // 普通标识符
BOOLEAN_LITERAL= true | false         // 布尔字面量
ESCAPED_IDENTIFIER = `[^`\n]+`       // 反引号包围的标识符
IDENTIFIER={ESCAPED_IDENTIFIER}|{PLAIN_IDENTIFIER}  // 完整标识符定义
FIELD_IDENTIFIER = \${IDENTIFIER}     // 字段标识符（以$开头）

%%
<YYINITIAL> {
  {WHITE_SPACE_CHAR}        { return WHITE_SPACE; }

  "package"            { return PACKAGE_KEYWORD; }
  "import"             { return IMPORT_KEYWORD; }
  "macro"              { return MACRO_KEYWORD; }
  "as"                 { return AS_KEYWORD; }
  "this"               { return THIS_KEYWORD; }
  "super"              { return SUPER_KEYWORD; }
  "public"             { return PUBLIC_KEYWORD; }
  "private"            { return PRIVATE_KEYWORD; }
  "protected"          { return PROTECTED_KEYWORD; }
  "internal"           { return INTERNAL_KEYWORD; }
  "class"              { return CLASS_KEYWORD; }
    "struct"          { return STRUCT_KEYWORD; }
  "interface"          { return INTERFACE_KEYWORD; }
      "func"               { return FUNC_KEYWORD; }
  "main"               { return MAIN_KEYWORD; }
  "let"                { return LET_KEYWORD; }
  "var"                { return VAR_KEYWORD; }
  "const"              { return CONST_KEYWORD; }
  "type"               { return TYPE_ALIAS_KEYWORD; }
  "init"               { return INIT_KEYWORD; }
  "if"                 { return IF_KEYWORD; }
  "else"               { return ELSE_KEYWORD; }
  "case"               { return CASE_KEYWORD; }
  "try"                { return TRY_KEYWORD; }
  "catch"              { return CATCH_KEYWORD; }
  "finally"            { return FINALLY_KEYWORD; }
  "for"                { return FOR_KEYWORD; }
  "do"                 { return DO_KEYWORD; }
  "while"              { return WHILE_KEYWORD; }
  "throw"              { return THROW_KEYWORD; }
  "return"             { return RETURN_KEYWORD; }
  "continue"           { return CONTINUE_KEYWORD; }
  "break"              { return BREAK_KEYWORD; }
  "is"                 { return IS_KEYWORD; }
  "in"                 { return IN_KEYWORD; }
  "match"              { return MATCH_KEYWORD; }
  "from"               { return FROM_KEYWORD; }
  "where"              { return WHERE_KEYWORD; }
  "extend"             { return EXTEND_KEYWORD; }
  "spawn"              { return SPAWN_KEYWORD; }
  "synchronized"       { return SYNCHRONIZED_KEYWORD; }
  "quote"              { return QUOTE_KEYWORD; }
  "static"             { return STATIC_KEYWORD; }
  "override"           { return OVERRIDE_KEYWORD; }
  "redef"              { return REDEF_KEYWORD; }
  "abstract"           { return ABSTRACT_KEYWORD; }
  "open"               { return OPEN_KEYWORD; }
  "operator"           { return OPERATOR_KEYWORD; }
  "foreign"            { return FOREIGN_KEYWORD; }
  "inout"              { return INOUT_KEYWORD; }
  "prop"               { return PROP_KEYWORD; }
  "mut"                { return MUT_KEYWORD; }
  "unsafe"             { return UNSAFE_KEYWORD; }
  "get"                { return GET_KEYWORD; }
  "set"                { return SET_KEYWORD; }
  "."                  { return DOT; }
  ","                  { return COMMA; }
  "("                  { return LPAREN; }
  ")"                  { return RPAREN; }
  "["                  { return LSQUARE; }
  "]"                  { return RSQUARE; }
  "{"                  { return LCURL; }
  "}"                  { return RCURL; }
  "**"                 { return EXP; }
  "*"                  { return MUL; }
  "%"                  { return MOD; }
  "/"                  { return DIV; }
  "+"                  { return ADD; }
  "-"                  { return SUB; }
  "|>"                 { return PIPELINE; }
  "~>"                 { return COMPOSITION; }
  "++"                 { return INC; }
  "--"                 { return DEC; }
  "&&"                 { return AND; }
  "||"                 { return OR; }
  "!"                  { return NOT; }
  "&"                  { return BITAND; }
  "|"                  { return BITOR; }
  "^"                  { return BITXOR; }
  "<<"                 { return LSHIFT; }
//  ">>"                 { return RSHIFT; }
  ":"                  { return COLON; }
  ";"                  { return SEMICOLON; }
  "="                  { return ASSIGN; }
  "+="                 { return ADD_ASSIGN; }
  "-="                 { return SUB_ASSIGN; }
  "*="                 { return MUL_ASSIGN; }
  "**="                { return EXP_ASSIGN; }
  "/="                 { return DIV_ASSIGN; }
  "%="                 { return MOD_ASSIGN; }
  "&&="                { return AND_ASSIGN; }
  "||="                { return OR_ASSIGN; }
  "&="                 { return BITAND_ASSIGN; }
  "|="                 { return BITOR_ASSIGN; }
  "^="                 { return BITXOR_ASSIGN; }
  "<<="                { return LSHIFT_ASSIGN; }
  ">>="                { return RSHIFT_ASSIGN; }
  "->"                 { return ARROW; }
  "<-"                 { return BACKARROW; }
  "=>"                 { return DOUBLE_ARROW; }
  "..."                { return ELLIPSIS; }
  "..="                { return CLOSEDRANGEOP; }
  ".."                 { return RANGEOP; }
  "#"                  { return HASH; }
  "@"                  { return AT; }
  "?"                  { return QUEST; }
  "<:"                 { return UPPERBOUND; }
  "<"                  { return LT; }
  ">"                  { return GT; }
  "<="                 { return LE; }
  ">="                 { return GE; }
  "!="                 { return NOTEQUAL; }
  "=="                 { return EQUAL; }
  "_"                  { return WILDCARD; }
  "\\\\"               { return BACKSLASH; }
  "`"                  { return QUOTESYMBOL; }
  "$"                  { return DOLLAR; }
  "\""                 { return STRING_QUOTE; }
  "\"\"\""             { return TRIPLE_STRING_QUOTE; }
  "${"                 { return STRING_EXPR_START; }

  // 整数类型
  "Int8"              { return INT8_KEYWORD; }
  "Int16"             { return INT16_KEYWORD; }
  "Int32"             { return INT32_KEYWORD; }
  "Int64"             { return INT64_KEYWORD; }
  "IntNative"         { return INTNATIVE_KEYWORD; }
  "UInt8"             { return UINT8_KEYWORD; }
  "UInt16"            { return UINT16_KEYWORD; }
  "UInt32"            { return UINT32_KEYWORD; }
  "UInt64"            { return UINT64_KEYWORD; }
  "UIntNative"        { return UINTNATIVE_KEYWORD; }

  // 浮点类型
  "Float16"           { return FLOAT16_KEYWORD; }
  "Float32"           { return FLOAT32_KEYWORD; }
  "Float64"           { return FLOAT64_KEYWORD; }

  // 字符类型
  "Rune"              { return RUNE_KEYWORD; }

  // 特殊类型
  "bool"              { return BOOL_KEYWORD; }
  "Unit"              { return UNIT_KEYWORD; }
  "Nothing"           { return NOTHING_KEYWORD; }
  "VArray"            { return VARRAY_KEYWORD; }

  {IDENTIFIER}        { return IDENTIFIER; }

}

[^] { return BAD_CHARACTER; }
